﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using System.IO;

namespace 向量应用
{
    public partial class Form1 : Form
    {
        AcadApplication AcadApp;
        AcadDocument AcadDoc;

        public Form1()
        {
            InitializeComponent();
        }

        private void 启动CAD()
        {
            try
            {
                AcadApp =
               (AcadApplication)System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Application");
                AcadDoc = AcadApp.ActiveDocument;
            }
            catch
            {
                OpenFileDialog pOpenDG = new OpenFileDialog();
                pOpenDG.Filter = "CAD文件(*.dwg)|*.dwg|CAD图形文件(*.dxf)|*.dxf";
                pOpenDG.Title = "打开CAD文件";
                pOpenDG.ShowDialog();
                string filePath = pOpenDG.FileName;
                if (filePath == "")
                {
                    MessageBox.Show("选择CAD文件无效！", "文件无效！");
                    Application.Exit();
                }
                AcadApp = new AcadApplication();
                AcadDoc = AcadApp.Documents.Open(filePath, null, null);
            }
            AcadApp.Application.Visible = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            启动CAD();
        }

        private void 判断线段方向_Click(object sender, EventArgs e)
        {
            handle01:
            Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption);
            object returnObj, pickPoint;
            string pickPrompt = "选取线条对象!";
            AcadDoc.Utility.GetEntity(out returnObj, out pickPoint, pickPrompt);
            AcadObject returnCADObj = (AcadObject)returnObj;
            if (returnCADObj.ObjectName == "AcDbPolyline")
            {
                ((AcadLWPolyline)returnCADObj).Highlight(true); double[]
               lineVertexCoords = (double[])((AcadLWPolyline)returnCADObj).Coordinates;
                if (lineVertexCoords.Length <= 4)
                {
                    MessageBox.Show("选择多段线的节点数应多于两个！");
                    goto handle01;
                }
                double result, a1, b1, a2, b2;
                a1 = lineVertexCoords[2] - lineVertexCoords[0];
                b1 = lineVertexCoords[3] - lineVertexCoords[1];
                a2 = lineVertexCoords[4] - lineVertexCoords[2];
                b2 = lineVertexCoords[5] - lineVertexCoords[3];
                result = (a1 * b2 - a2 * b1);
                if (result > 0)
                {
                    MessageBox.Show("选择的多段线按逆时针方向绘制！");
                }
                else
                {
                    MessageBox.Show("选择的多段线按顺时针方向绘制！");
                }
            }
            else
            {
                MessageBox.Show("选择的不是多段线！请重新选择！");
                goto handle01;
            }
            Microsoft.VisualBasic.Interaction.AppActivate(this.Text);
        }

        private void 获取面片_Click(object sender, EventArgs e)
        {
            Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption);
            object returnObj, pickPoint;
            string pickPrompt = "选取面片对象!";
            AcadDoc.Utility.GetEntity(out returnObj, out pickPoint, pickPrompt);
            AcadObject returnCADObj = (AcadObject)returnObj;
            if (returnCADObj.ObjectName == "AcDbFace")
            {
                double[] vertexCoords = (double[])(((Acad3DFace)returnCADObj).Coordinates);
                bool IsOrNotTrian;
                IsOrNotTrian = JudgeTriaFace(vertexCoords, out vertexCoords);
                int result;
                result = JudgeFaceNormal(vertexCoords);
                if (result == 1)
                {
                    MessageBox.Show("选择面片为正向面片！");
                }
                else if (result == -1)
                {
                    double[] point1 = new double[3], point2 = new double[3], point3 = new double[3],
point4 = new double[3];
                    point1[0] = vertexCoords[0]; point1[1] = vertexCoords[1]; point1[2] =
                   vertexCoords[2];
                    point2[0] = vertexCoords[3]; point2[1] = vertexCoords[4]; point2[2] =
                   vertexCoords[5];
                    point3[0] = vertexCoords[6]; point3[1] = vertexCoords[7]; point3[2] =
vertexCoords[8];
                    point4[0] = vertexCoords[9]; point4[1] = vertexCoords[10]; point4[2] =
                   vertexCoords[11];
                    AcadDoc.ModelSpace.Add3DFace(point4, point3, point2, point1);
                    returnCADObj.Delete();
                    MessageBox.Show("选择面片为反向面片！更改方向面片");
                }
                else if (result == 0)
                {
                    MessageBox.Show("选择面片为垂直面片！");
                }
                //MessageBox.Show("选择对象为面片对象！");
            }
        }

        private bool JudgeTriaFace(double[] vertexCoords01, out double[] vertexCoords02)
        {
            double[] myVertexCoords = new double[12];
            myVertexCoords = vertexCoords01;
            bool resultBool = false;
            int i, j = 0;
            for (i = 0; i < 4; i++)
            {
                for (j = 0; j < 4; j++)
                {
                    if (i == j) continue;
                    if (myVertexCoords[3 * i] == myVertexCoords[3 * j] & myVertexCoords[3 * i + 1]
                   == myVertexCoords[3 * j + 1]
                    & myVertexCoords[3 * i + 2] == myVertexCoords[3 * j + 2])
                    {
                        resultBool = true;
                        break;
                    }
                }
            }
            if (j != 3)
            {
                for (i = j; i < 3; i++)
                {
                    myVertexCoords[3 * i] = myVertexCoords[3 * i + 3];
                    myVertexCoords[3 * i + 1] = myVertexCoords[3 * i + 4];
                    myVertexCoords[3 * i + 2] = myVertexCoords[3 * i + 5];
                }
            }
            vertexCoords02 = myVertexCoords;
            return resultBool;
        }

        private int JudgeFaceNormal(double[] vertexCoords)
        {
            int result = 2;
            double vectorResult, a1, b1, a2, b2;
            a1 = vertexCoords[3] - vertexCoords[0];
            b1 = vertexCoords[4] - vertexCoords[1];
            a2 = vertexCoords[6] - vertexCoords[3];
            b2 = vertexCoords[7] - vertexCoords[4];
            vectorResult = (a1 * b2 - a2 * b1);
            if (vectorResult > 0)
            {
                result = 1;
            }
            else if (vectorResult < 0)
            {
                result = -1;
            }
            else
            {
                result = 0;
            }
            return result;
        }

        private void 批量选择更改面片方向_Click(object sender, EventArgs e)
        {
            Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption);
            AcadSelectionSet mySelectionSet;
            mySelectionSet = AcadDoc.SelectionSets.Add("NewSelectionSet011");
            Int16[] FilterType = new Int16[1];
            object[] FilterData = new object[1];
            FilterType[0] = 0;
            FilterData[0] = "3DFACE";
            mySelectionSet.SelectOnScreen(FilterType, FilterData);
            int antiFcaeCount = 0;
            foreach (AcadObject returnCADObj in mySelectionSet)
            {
                if (returnCADObj.ObjectName == "AcDbFace")
                {
                    double[] vertexCoords = (double[])(((Acad3DFace)returnCADObj).Coordinates);
                    bool IsOrNotTrian;
                    IsOrNotTrian = JudgeTriaFace(vertexCoords, out vertexCoords);
                    int result;
                    result = JudgeFaceNormal(vertexCoords);

                    if (result == -1)
                    {
                        double[] point1 = new double[3], point2 = new double[3], point3 = new double[3],
                       point4 = new double[3];
                        point1[0] = vertexCoords[0]; point1[1] = vertexCoords[1]; point1[2] =
                       vertexCoords[2];
                        point2[0] = vertexCoords[3]; point2[1] = vertexCoords[4]; point2[2] =
                       vertexCoords[5];
                        point3[0] = vertexCoords[6]; point3[1] = vertexCoords[7]; point3[2] =
                       vertexCoords[8];
                        point4[0] = vertexCoords[9]; point4[1] = vertexCoords[10]; point4[2] =
                       vertexCoords[11];
                        AcadDoc.ModelSpace.Add3DFace(point4, point3, point2, point1);
                        returnCADObj.Delete();
                        antiFcaeCount++;
                    }
                }
            }
            AcadDoc.SelectionSets.Item("NewSelectionSet011").Delete();
            Microsoft.VisualBasic.Interaction.AppActivate(this.Text);
            MessageBox.Show("选择集中共有" + antiFcaeCount.ToString() + "个反向面片！");
        }
    }
}
